#!/usr/bin/env python3
import subprocess
import sys

# 获取当前分支名
def get_current_branch():
    # 通过 git 命令获取当前分支名
    result = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], capture_output=True, text=True)
    if result.returncode != 0:
        print('无法获取当前分支名')
        sys.exit(1)
    return result.stdout.strip()

# 拉取远程分支最新信息（不合并，只更新引用）
def fetch_remote():
    # 执行 git fetch，获取远程仓库最新状态
    result = subprocess.run(['git', 'fetch'], capture_output=True, text=True)
    if result.returncode != 0:
        print('git fetch 失败')
        sys.exit(1)
        

# 检查当前分支与远程分支的差异，判断是否有未拉取的提交
def check_unpulled_commits(branch):
    # 组装远程分支名
    remote_branch = f'origin/{branch}'
    # 统计本地分支与远程分支之间的提交差异数量
    result = subprocess.run(['git', 'rev-list', f'HEAD..{remote_branch}', '--count'], capture_output=True, text=True)
    if result.returncode != 0:
        print('无法比较本地与远程分支')
        sys.exit(1)
    count = int(result.stdout.strip())
    return count

# 检查本地修改与远程分支合并时是否存在冲突
def check_merge_conflict(branch):
    # 尝试合并远程分支到本地（不提交），检测是否有冲突
    result = subprocess.run(
        ['git', 'merge', '--no-commit', '--no-ff', f'origin/{branch}'],
        capture_output=True, text=True
    )
    if result.returncode != 0:
        # 撤销未完成的合并，避免污染工作区
        subprocess.run(['git', 'merge', '--abort'], capture_output=True, text=True)
        return True
    # 如果没有冲突，撤销合并操作
    subprocess.run(['git', 'reset', '--hard', 'HEAD'], capture_output=True, text=True)
    return False

# 主流程入口
def main():
    # 检查命令行参数
    skip_conflict_check = False
    if len(sys.argv) > 1 and sys.argv[1] == '--skip-conflict-check':
        skip_conflict_check = True
    branch = get_current_branch()
    fetch_remote()
    unpulled = check_unpulled_commits(branch)
    if unpulled > 0:
        if skip_conflict_check and check_merge_conflict(branch):
            # 检查是否有合并冲突，除非跳过
            print(f'本地修改与远程分支 {branch} 存在冲突，已经通过检测！')
            sys.exit(0)
        else:
            print(f'当前分支 {branch} 有 {unpulled} 个未拉取的远程提交，请先执行 git pull 再提交！')
            sys.exit(1)
        

if __name__ == '__main__':
    main()
